﻿#include "FITKAbaqusAdaptorConnectorPlasticityBehavior.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "InpReadInformationMapper.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractAssInstance.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorSection.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorBehaviorPlasticity.h"
#include <QDebug>
//命名空间
namespace IO
{
    QString FITKAbaqusAdaptorConnectorPlasticityBehavior::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorConnectorPlasticityBehavior";
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::adaptR()
    {
        _sectionConnectorData = dynamic_cast<Interface::FITKAbaConnectorSection*>(_dataObj);
        if (!_sectionConnectorData || !_reader)return false;
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        if (!line.toLower().startsWith("*connector plasticity")) return false;
        //添加行为
        _plasticityBehaviorData = dynamic_cast<Interface::FITKAbaConnectorBehaviorPlasticity*>
            (_sectionConnectorData->addBehavior(Interface::FITKAbaConnectorBehaviorEnum::ConnectorBehaviorType::Plasticity));
        if (!_plasticityBehaviorData)return false;
        //关键字处理
        bool readOK = true;
        InpKeyLineSpliter s(line, _reader);
        //力矩类型
        if (s.hasKey("component"))
        {
            this->_component = s["component"].trimmed().toInt(&readOK);
            if (!readOK)return false;
            if (_component < 1 || _component > 6)return false;
            std::array<bool, 6> forceMoment{ false, false, false, false, false, false };
            forceMoment[_component - 1] = true;
            _plasticityBehaviorData->setForceMoment(forceMoment);
            _plasticityBehaviorData->setCoupling(Interface::FITKAbaConnectorBehaviorEnum::Coupling::Uncoupled);
        }
        else
            _plasticityBehaviorData->setCoupling(Interface::FITKAbaConnectorBehaviorEnum::Coupling::Coupled);
        //读取数据
        while (!_reader->atEnd())
        {
            line = _reader->readLine();
            if (!line.startsWith("*")) continue;
            s.reset(line);
            QString sH = s.getHeader().toLower();
            QString type = s["type"].trimmed().toLower();
            if (sH == "connector hardening" && (type.isEmpty() || type == "isotropic"))
                readOK = this->readIsotropicHardening();
            else if (sH == "connector hardening" && type == "kinematic")
                readOK = this->readKinematicHardening();
            else if (sH == "connector potential")
                readOK = this->readForcePotential();
            else
                return true;

            if (readOK)
                _reader->backLine();
        }
        if (!readOK)
            _sectionConnectorData->removeBehavior(_plasticityBehaviorData);
        return false;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::adaptW()
    {
        _sectionConnectorData = dynamic_cast<Interface::FITKAbaConnectorSection*>(_dataObj);
        if (!_sectionConnectorData || !_plasticityBehaviorData || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        bool writeOK = false;
        //获取类型
        Interface::FITKAbaConnectorBehaviorEnum::Coupling type = _plasticityBehaviorData->getCoupling();
        if (type == Interface::FITKAbaConnectorBehaviorEnum::Coupling::Uncoupled)
        {
            std::array<bool, 6> forceMomentState = _plasticityBehaviorData->getForceMoment();
            for (int i = 0; i < 6; ++i)
            {
                if (!forceMomentState[i])continue;
                *stream << QString("*Connector Plasticity, component=%1").arg(i + 1) << endl;
                if (_plasticityBehaviorData->getSpecifyHardening())
                {
                    writeOK = this->writeIsotropicHardening();
                    if (!writeOK)return false;
                }
                if (_plasticityBehaviorData->getSpecifyKinematicHardening())
                {
                    writeOK = this->writeKinematicHardening();
                    if (!writeOK)return false;
                }
            }
        }
        else if (type == Interface::FITKAbaConnectorBehaviorEnum::Coupling::Coupled)
        {
            *stream << QString("*Connector Plasticity") << endl;
            if (_plasticityBehaviorData->getSpecifyHardening())
            {
                writeOK = this->writeIsotropicHardening();
                if (!writeOK)return false;
            }
            if (_plasticityBehaviorData->getSpecifyKinematicHardening())
            {
                writeOK = this->writeKinematicHardening();
                if (!writeOK)return false;
            }
            writeOK = this->writeForcePotential();
        }

        return writeOK;
    }

    void FITKAbaqusAdaptorConnectorPlasticityBehavior::setWriteBehaviorData(Interface::FITKAbaConnectorBehaviorPlasticity* plasticityData)
    {
        _plasticityBehaviorData = plasticityData;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::readIsotropicHardening()
    {
        if (!_plasticityBehaviorData || !_reader)return false;
        //设置指定各向同性硬化
        _plasticityBehaviorData->setSpecifyHardening(true);
        //回退一行，处理关键字信息
        _reader->backLine();
        QString line = _reader->readLine();
        InpKeyLineSpliter s(line, _reader);
        bool ok = false;
        //场变量个数
        if (s.hasKey("dependencies"))
        {
            this->_dependencies = s["dependencies"].trimmed().toInt(&ok);
            if (!ok)return false;
        }
        //定义类型
        QString definition = s["definition"].trimmed().toUpper();
        if (definition.isEmpty())return false;
        if (definition == "TABULAR")
            ok = this->readIsotropicHardeningTabular();
        else if (definition == "EXPONENTIAL LAW")
            ok = this->readIsotropicHardeningExponentialLaw();
        return ok;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::writeIsotropicHardening()
    {
        if (!_plasticityBehaviorData || !_writer)return false;
        bool writeOK = false;
        Interface::FITKAbaConnectorBehaviorEnum::PlacticityIsoTropicHardeningDefinition definitionType = _plasticityBehaviorData->getIsoHardenDefinition();
        if (definitionType == Interface::FITKAbaConnectorBehaviorEnum::PlacticityIsoTropicHardeningDefinition::Tabular)
            writeOK = this->writeIsotropicHardeningTabular();
        else if (definitionType == Interface::FITKAbaConnectorBehaviorEnum::PlacticityIsoTropicHardeningDefinition::ExponentialLaw)
            writeOK = this->writeIsotropicHardeningExponentialLaw();
        return writeOK;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::readIsotropicHardeningTabular()
    {
        if (!_plasticityBehaviorData || !_reader)return false;
        //定义表格类型
        _plasticityBehaviorData->setIsoHardenDefinition(Interface::FITKAbaConnectorBehaviorEnum::PlacticityIsoTropicHardeningDefinition::Tabular);
        //文件应有的一次数据所具有的行数
        int rowParaNum = (3 + 1 + _dependencies) % 8 ? (3 + 1 + _dependencies) / 8 + 1 : (3 + 1 + _dependencies) / 8;
        //获取数据
        bool ok = false;
        int  num = 0;
        int index = 0;
        while (!_reader->atEnd())
        {
            QString line = _reader->readLine().trimmed();
            if (line.startsWith("*"))break;
            //动态设置行数
            _plasticityBehaviorData->setIsoHardenTabDataRowCount(index + 1);
            //移除最后一个,预防干扰
            if (line.endsWith(','))line.chop(1);
            QStringList str = line.trimmed().split(',');
            for (int j = 0; j < 8 && j < str.size(); ++j)
            {
                ++num;
                if (num == 4 && str.at(j).trimmed().isEmpty())continue;
                //读取数据
                double v = str.at(j).trimmed().toDouble(&ok);
                if (!ok)return false;
                //对应数据设置
                if (num == 1)
                    _plasticityBehaviorData->getIsoHardenTabDataRow(index).setYieldForceMoment(v);
                else if (num == 2)
                    _plasticityBehaviorData->getIsoHardenTabDataRow(index).setPlasticMotion(v);
                else if (num == 3)
                    _plasticityBehaviorData->getIsoHardenTabDataRow(index).setRate(v);
            }
            if (num % 8 != 0 || num / 8 == rowParaNum)
            {
                ++index;
                if (num < 3)return false;
                num = 0;
            }
        }
        return true;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::writeIsotropicHardeningTabular()
    {
        if (!_plasticityBehaviorData || !_writer)return false;
        QTextStream* stream = _writer->getStream();
        *stream << QString("*Connector Hardening, definition=TABULAR") << endl;
        //获取行数
        int rowCount = _plasticityBehaviorData->getIsoHardenTabDataRowCount();
        for (int i = 0; i < rowCount; ++i)
        {
            double yieldForceMoment = _plasticityBehaviorData->getIsoHardenTabDataRow(i).getYieldForceMoment();
            double plasticMotion = _plasticityBehaviorData->getIsoHardenTabDataRow(i).getPlasticMotion();
            double rate = _plasticityBehaviorData->getIsoHardenTabDataRow(i).getRate();
            *stream << QString("%1,%2,%3").arg(_writer->double2String(yieldForceMoment, 8, 0)).arg(_writer->double2String(plasticMotion, 8, 0)).arg(_writer->double2String(rate, 8, 0)) << endl;
        }
        return true;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::readIsotropicHardeningExponentialLaw()
    {
        if (!_plasticityBehaviorData || !_reader)return false;
        //定义指数定律类型
        _plasticityBehaviorData->setIsoHardenDefinition(Interface::FITKAbaConnectorBehaviorEnum::PlacticityIsoTropicHardeningDefinition::ExponentialLaw);
        return false;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::writeIsotropicHardeningExponentialLaw()
    {
        return false;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::readKinematicHardening()
    {
        if (!_plasticityBehaviorData || !_reader)return false;
        //设置指定运动性硬性
        _plasticityBehaviorData->setSpecifyKinematicHardening(true);

        return false;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::writeKinematicHardening()
    {
        return false;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::readForcePotential()
    {
        return false;
    }

    bool FITKAbaqusAdaptorConnectorPlasticityBehavior::writeForcePotential()
    {
        return false;
    }
}